/*     */ package com.zimbra.cs.volume;
/*     */ 
/*     */ import com.google.common.base.Objects;
/*     */ import com.google.common.base.Objects.ToStringHelper;
/*     */ import com.google.common.base.Strings;
/*     */ import com.zimbra.common.localconfig.KnownKey;
/*     */ import com.zimbra.common.localconfig.LC;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.account.Server;
/*     */ import com.zimbra.cs.mailbox.Metadata;
/*     */ import com.zimbra.cs.store.IncomingDirectory;
/*     */ import com.zimbra.cs.util.Zimbra;
/*     */ import com.zimbra.soap.admin.type.VolumeInfo;
/*     */ import java.io.File;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public final class Volume
/*     */ {
/*     */   public static final short ID_AUTO_INCREMENT = -1;
/*     */   public static final short ID_NONE = -2;
/*     */   public static final short ID_MAX = 255;
/*     */   public static final short TYPE_MESSAGE = 1;
/*     */   public static final short TYPE_MESSAGE_SECONDARY = 2;
/*     */   public static final short TYPE_INDEX = 10;
/*     */   private static final String SUBDIR_MESSAGE = "msg";
/*     */   private static final String SUBDIR_INDEX = "index";
/*     */   private static final String INCOMING_DIR = "incoming";
/*  53 */   private short id = -1;
/*     */   private short type;
/*     */   private String name;
/*     */   private String rootPath;
/*     */   private String incomingMsgDir;
/*     */   private IncomingDirectory incoming;
/*  59 */   private short mboxGroupBits = 8;
/*  60 */   private short mboxBits = 12;
/*  61 */   private short fileGroupBits = 8;
/*  62 */   private short fileBits = 12;
/*     */   private int mboxGroupBitmask;
/*     */   private int fileGroupBitmask;
/*     */   private boolean compressBlobs;
/*     */   private long compressionThreshold;
/*     */   private Metadata metadata;
/*     */   
/*     */   public static class VolumeMetadata
/*     */   {
/*     */     private int lastSyncDate;
/*     */     private int currentSyncDate;
/*     */     private int groupId;
/*     */     private static final String FN_DATE_LASTSYNC = "lsd";
/*     */     private static final String FN_DATE_CURRENTSYNC = "csd";
/*     */     private static final String FN_LAST_GROUP_ID = "gid";
/*     */     
/*     */     Metadata serialize() {
/*  79 */       Metadata meta = new Metadata();
/*  80 */       meta.put("lsd", this.lastSyncDate);
/*  81 */       meta.put("csd", this.currentSyncDate);
/*  82 */       meta.put("gid", this.groupId);
/*  83 */       return meta;
/*     */     }
/*     */     
/*     */     public VolumeMetadata(Metadata meta) throws ServiceException {
/*  87 */       this.lastSyncDate = meta.getInt("lsd", 0);
/*  88 */       this.currentSyncDate = meta.getInt("csd", 0);
/*  89 */       this.groupId = meta.getInt("gid", 0);
/*     */     }
/*     */     
/*     */     public VolumeMetadata(int lastSyncDate, int currentSyncDate, int groupId) {
/*  93 */       this.lastSyncDate = lastSyncDate;
/*  94 */       this.currentSyncDate = currentSyncDate;
/*  95 */       this.groupId = groupId;
/*     */     }
/*     */     
/*     */     public int getLastSyncDate() {
/*  99 */       return this.lastSyncDate;
/*     */     }
/*     */     
/*     */     public int getCurrentSyncDate() {
/* 103 */       return this.currentSyncDate;
/*     */     }
/*     */     
/*     */     public int getGroupId() {
/* 107 */       return this.groupId;
/*     */     }
/*     */     
/*     */     public void setLastSyncDate(int date) {
/* 111 */       this.lastSyncDate = date;
/*     */     }
/*     */     
/*     */     public void setCurrentSyncDate(int date) {
/* 115 */       this.currentSyncDate = date;
/*     */     }
/*     */     
/*     */     public void setGroupId(int id) {
/* 119 */       this.groupId = id;
/*     */     }
/*     */     
/*     */     public String toString() {
/* 123 */       return serialize().toString();
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public static Builder builder()
/*     */   {
/* 131 */     return new Builder(null);
/*     */   }
/*     */   
/*     */   public static Builder builder(Volume copy) {
/* 135 */     return new Builder(copy, null);
/*     */   }
/*     */   
/*     */   public static final class Builder {
/* 139 */     private final Volume volume = new Volume(null);
/*     */     
/*     */     private Builder() {}
/*     */     
/*     */     private Builder(Volume copy)
/*     */     {
/* 145 */       this.volume.id = copy.id;
/* 146 */       this.volume.type = copy.type;
/* 147 */       this.volume.name = copy.name;
/* 148 */       this.volume.rootPath = copy.rootPath;
/* 149 */       this.volume.mboxGroupBits = copy.mboxGroupBits;
/* 150 */       this.volume.mboxBits = copy.mboxBits;
/* 151 */       this.volume.fileGroupBits = copy.fileGroupBits;
/* 152 */       this.volume.fileBits = copy.fileBits;
/* 153 */       this.volume.compressBlobs = copy.compressBlobs;
/* 154 */       this.volume.compressionThreshold = copy.compressionThreshold;
/* 155 */       this.volume.metadata = copy.metadata;
/*     */     }
/*     */     
/*     */     public Builder setId(short id)
/*     */     {
/* 160 */       this.volume.id = id;
/* 161 */       return this;
/*     */     }
/*     */     
/*     */     public Builder setType(short type) {
/* 165 */       this.volume.type = type;
/* 166 */       return this;
/*     */     }
/*     */     
/*     */     public Builder setName(String name) {
/* 170 */       this.volume.name = name;
/* 171 */       return this;
/*     */     }
/*     */     
/*     */     public Builder setPath(String path, boolean normalize) throws VolumeServiceException, ServiceException {
/* 175 */       if (normalize) {
/* 176 */         path = this.volume.normalizePath(path);
/* 177 */         VolumeManager.getInstance().validatePath(path);
/*     */       }
/*     */       
/* 180 */       this.volume.rootPath = path;
/* 181 */       return this;
/*     */     }
/*     */     
/*     */     public Builder setMboxGroupBits(short bits) {
/* 185 */       this.volume.mboxGroupBits = bits;
/* 186 */       return this;
/*     */     }
/*     */     
/*     */     public Builder setMboxBit(short bits) {
/* 190 */       this.volume.mboxBits = bits;
/* 191 */       return this;
/*     */     }
/*     */     
/*     */     public Builder setFileGroupBits(short bits) {
/* 195 */       this.volume.fileGroupBits = bits;
/* 196 */       return this;
/*     */     }
/*     */     
/*     */     public Builder setFileBits(short bits) {
/* 200 */       this.volume.fileBits = bits;
/* 201 */       return this;
/*     */     }
/*     */     
/*     */     public Builder setCompressBlobs(boolean value) {
/* 205 */       this.volume.compressBlobs = value;
/* 206 */       return this;
/*     */     }
/*     */     
/*     */     public Builder setCompressionThreshold(long value) {
/* 210 */       this.volume.compressionThreshold = value;
/* 211 */       return this;
/*     */     }
/*     */     
/*     */     public Builder setMetadata(Volume.VolumeMetadata metadata) {
/* 215 */       this.volume.metadata = metadata.serialize();
/* 216 */       return this;
/*     */     }
/*     */     
/*     */     public Volume build() throws VolumeServiceException {
/* 220 */       switch (this.volume.id) {
/*     */       case -2: 
/*     */       case -1: 
/*     */         break;
/*     */       default: 
/* 225 */         if ((this.volume.id < 1) || (this.volume.id > 255)) {
/* 226 */           throw VolumeServiceException.ID_OUT_OF_RANGE(this.volume.id);
/*     */         }
/*     */         break;
/*     */       }
/*     */       
/* 231 */       switch (this.volume.type) {
/*     */       case 1: 
/*     */       case 2: 
/*     */       case 10: 
/*     */         break;
/*     */       default: 
/* 237 */         throw VolumeServiceException.INVALID_REQUEST("Invalid volume type: " + this.volume.type);
/*     */       }
/*     */       
/* 240 */       if (Strings.isNullOrEmpty(this.volume.name)) {
/* 241 */         throw VolumeServiceException.INVALID_REQUEST("Missing volume name");
/*     */       }
/* 243 */       if (Strings.isNullOrEmpty(this.volume.rootPath)) {
/* 244 */         throw VolumeServiceException.INVALID_REQUEST("Missing volume path");
/*     */       }
/* 246 */       if (this.volume.compressionThreshold < 0L) {
/* 247 */         throw VolumeServiceException.INVALID_REQUEST("compressionThreshold cannot be a negative number");
/*     */       }
/*     */       
/* 250 */       this.volume.incomingMsgDir = (this.volume.rootPath + File.separator + "incoming");
/* 251 */       switch (this.volume.type) {
/*     */       case 1: 
/*     */       case 2: 
/* 254 */         this.volume.incoming = new IncomingDirectory(this.volume.incomingMsgDir);
/*     */       }
/*     */       
/* 257 */       this.volume.mboxGroupBitmask = ((int)(Math.pow(2.0D, this.volume.mboxGroupBits) - 1L));
/* 258 */       this.volume.fileGroupBitmask = ((int)(Math.pow(2.0D, this.volume.fileGroupBits) - 1L));
/* 259 */       if (this.volume.metadata == null) {
/* 260 */         this.volume.metadata = new Volume.VolumeMetadata(0, 0, 0).serialize();
/*     */       }
/* 262 */       return this.volume;
/*     */     }
/*     */   }
/*     */   
/*     */   public short getId() {
/* 267 */     return this.id;
/*     */   }
/*     */   
/*     */   public short getType() {
/* 271 */     return this.type;
/*     */   }
/*     */   
/*     */   public String getName() {
/* 275 */     return this.name;
/*     */   }
/*     */   
/*     */   public String getLocator() {
/* 279 */     return Short.toString(getId());
/*     */   }
/*     */   
/*     */   public String getRootPath() {
/* 283 */     return this.rootPath;
/*     */   }
/*     */   
/*     */   public String getIncomingMsgDir() {
/* 287 */     return this.incomingMsgDir;
/*     */   }
/*     */   
/*     */   public IncomingDirectory getIncomingDirectory() {
/* 291 */     return this.incoming;
/*     */   }
/*     */   
/*     */   public short getMboxGroupBits() {
/* 295 */     return this.mboxGroupBits;
/*     */   }
/*     */   
/*     */   public short getMboxBits() {
/* 299 */     return this.mboxBits;
/*     */   }
/*     */   
/*     */   public short getFileGroupBits() {
/* 303 */     return this.fileGroupBits;
/*     */   }
/*     */   
/*     */   public short getFileBits() {
/* 307 */     return this.fileBits;
/*     */   }
/*     */   
/*     */   public boolean isCompressBlobs() {
/* 311 */     return this.compressBlobs;
/*     */   }
/*     */   
/*     */   public long getCompressionThreshold() {
/* 315 */     return this.compressionThreshold;
/*     */   }
/*     */   
/*     */   public VolumeMetadata getMetadata() throws ServiceException {
/* 319 */     return new VolumeMetadata(this.metadata);
/*     */   }
/*     */   
/*     */   public static String getAbsolutePath(String path) throws ServiceException
/*     */   {
/* 324 */     return LC.zimbra_relative_volume_path.booleanValue() ? LC.zimbra_home.value() + File.separator + path : path;
/*     */   }
/*     */   
/*     */   public static String getConfiguredServerID() throws ServiceException
/*     */   {
/* 329 */     StringBuilder finalPath = new StringBuilder();
/* 330 */     if (Zimbra.isAlwaysOn())
/*     */     {
/* 332 */       String alwaysOnServerClusterId = Zimbra.getAlwaysOnClusterId();
/* 333 */       String localServerId = Provisioning.getInstance().getLocalServer().getId();
/* 334 */       if (alwaysOnServerClusterId != null)
/*     */       {
/* 336 */         finalPath.append(alwaysOnServerClusterId);
/*     */       }
/*     */       else
/*     */       {
/* 340 */         finalPath.append(localServerId);
/*     */       }
/*     */     }
/*     */     else
/*     */     {
/* 345 */       String localServerId = Provisioning.getInstance().getLocalServer().getId();
/* 346 */       finalPath.append(localServerId);
/*     */     }
/* 348 */     return finalPath.toString();
/*     */   }
/*     */   
/*     */   private StringBuilder getMailboxDir(int mboxId, String subdir) throws ServiceException {
/* 352 */     StringBuilder result = new StringBuilder();
/* 353 */     int dir = mboxId >> this.mboxBits & this.mboxGroupBitmask;
/*     */     
/* 355 */     result.append(this.rootPath).append(File.separator);
/*     */     
/* 357 */     if (Provisioning.getInstance().getLocalServer().isConfiguredServerIDForBlobDirEnabled()) {
/* 358 */       result.append(getConfiguredServerID()).append(File.separator);
/*     */     }
/* 360 */     result.append(dir).append(File.separator).append(mboxId);
/*     */     
/* 362 */     if (subdir != null) {
/* 363 */       result.append(File.separator).append(subdir);
/*     */     }
/* 365 */     return result;
/*     */   }
/*     */   
/*     */   public String getMailboxDir(int mboxId, short type) throws ServiceException {
/* 369 */     return getMailboxDir(mboxId, type == 10 ? "index" : "msg").toString();
/*     */   }
/*     */   
/*     */   public String getBlobDir(int mboxId, int itemId) throws ServiceException {
/* 373 */     long dir = itemId >> this.fileBits & this.fileGroupBitmask;
/* 374 */     return File.separator + dir;
/*     */   }
/*     */   
/*     */   public String getMessageRootDir(int mboxId) throws ServiceException {
/* 378 */     return getMailboxDir(mboxId, null).toString();
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private String normalizePath(String path)
/*     */     throws VolumeServiceException
/*     */   {
/* 393 */     if (LC.zimbra_relative_volume_path.booleanValue()) {
/* 394 */       return path;
/*     */     }
/* 396 */     StringBuilder result = new StringBuilder();
/* 397 */     if (path.matches("^[a-zA-Z]:[/\\\\].*$"))
/*     */     {
/* 399 */       result.append(path.substring(0, 2)).append(File.separator);
/* 400 */       path = path.substring(3);
/* 401 */     } else if ((path.length() >= 2) && (path.substring(0, 2).equals("\\\\")))
/*     */     {
/* 403 */       result.append("\\\\");
/* 404 */       String original = path;
/* 405 */       path = path.substring(2);
/* 406 */       int slash = path.indexOf('/');
/* 407 */       int backslash = path.indexOf('\\');
/* 408 */       if (slash < 0) {
/* 409 */         slash = path.length();
/*     */       }
/* 411 */       if (backslash < 0) {
/* 412 */         backslash = path.length();
/*     */       }
/* 414 */       backslash = Math.min(slash, backslash);
/* 415 */       if (backslash >= 0) {
/* 416 */         result.append(path.substring(0, backslash)).append(File.separator);
/* 417 */         path = path.substring(backslash + 1);
/*     */       } else {
/* 419 */         throw VolumeServiceException.NOT_ABSOLUTE_PATH(original);
/*     */       }
/* 421 */     } else if ((path.charAt(0) == '/') || (path.charAt(0) == '\\')) {
/* 422 */       result.append(File.separator);
/* 423 */       path = path.substring(1);
/*     */     } else {
/* 425 */       throw VolumeServiceException.NOT_ABSOLUTE_PATH(path);
/*     */     }
/*     */     
/* 428 */     String[] dirs = path.split("[/\\\\]");
/* 429 */     if (dirs.length == 0) {
/* 430 */       return result.toString();
/*     */     }
/* 432 */     String[] newDirs = new String[dirs.length];
/* 433 */     int numDirs = 0;
/* 434 */     for (int i = 0; i < dirs.length; i++) {
/* 435 */       String dir = dirs[i];
/*     */       
/* 437 */       if ((!dir.isEmpty()) && (!dir.equals(".")) && ((dir.length() <= 2) || (!dir.matches("^\\.+$"))))
/*     */       {
/*     */ 
/* 440 */         if (dir.equals("..")) {
/* 441 */           if (numDirs > 0) {
/* 442 */             numDirs--;
/*     */           }
/*     */         } else {
/* 445 */           newDirs[numDirs] = dir;
/* 446 */           numDirs++;
/*     */         }
/*     */       }
/*     */     }
/* 450 */     for (int i = 0; i < numDirs; i++) {
/* 451 */       result.append(newDirs[i]);
/* 452 */       if (i < numDirs - 1) {
/* 453 */         result.append(File.separator);
/*     */       }
/*     */     }
/* 456 */     return result.toString();
/*     */   }
/*     */   
/*     */ 
/*     */   public String toString()
/*     */   {
/* 462 */     return Objects.toStringHelper(this).add("id", this.id).add("type", this.type).add("name", this.name).add("path", this.rootPath).add("mboxGroupBits", this.mboxGroupBits).add("mboxBits", this.mboxBits).add("fileGroupBits", this.fileGroupBits).add("fileBits", this.fileBits).add("compressBlobs", this.compressBlobs).add("compressionThreshold", this.compressionThreshold).toString();
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public VolumeInfo toJAXB()
/*     */   {
/* 471 */     VolumeInfo jaxb = new VolumeInfo();
/* 472 */     jaxb.setId(this.id);
/* 473 */     jaxb.setType(this.type);
/* 474 */     jaxb.setName(this.name);
/* 475 */     jaxb.setRootPath(this.rootPath);
/* 476 */     jaxb.setMgbits(this.mboxGroupBits);
/* 477 */     jaxb.setMbits(this.mboxBits);
/* 478 */     jaxb.setFgbits(this.fileGroupBits);
/* 479 */     jaxb.setFbits(this.fileBits);
/* 480 */     jaxb.setCompressBlobs(Boolean.valueOf(this.compressBlobs));
/* 481 */     jaxb.setCompressionThreshold(this.compressionThreshold);
/* 482 */     jaxb.setCurrent(VolumeManager.getInstance().isCurrent(this));
/* 483 */     return jaxb;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/volume/Volume.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */